package info_serv

import (
	"ubt-rbac-service/internal/app/model"
	"ubt-rbac-service/internal/app/model/info_mod"
	"ubt-rbac-service/internal/app/util"
	"strconv"
	"strings"
)

type infoServ struct{}

var InfoServ = infoServ{}

// Add 新增资讯
func (s *infoServ) Add(req *info_mod.InfoSaveReq) *model.Result {
	sqlStr := "INSERT INTO information(fst_title, sec_title, kind, info_type, sort, src, begin_time, end_time, " +
		"cmted, describ, contents, fst_img_url, img_urls, file_urls, file_names, visit_num, good_num, cmt_num, tag_ids, " +
		"tag_names, states, add_time, fst_img_id, fst_img_name, img_ids, img_names, file_ids, opt_org) " +
		"VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18, $19, $20, " +
		"3, EXTRACT(EPOCH FROM NOW()), $21, $22, $23, $24, $25, $26)"
	retCode, retMsg := util.CudData(sqlStr, req.FstTitle, req.SecTitle, req.Kind, req.InfoType, req.Sort,
		req.Src, req.BeginTime, req.EndTime, req.Cmted, req.Describ, req.Contents, req.FstImgUrl, req.ImgUrls, req.FileUrls,
		req.FileNames, req.VisitNum, req.GoodNum, req.CmtNum, req.TagIds, req.TagNames,
		req.FstImgId, req.FstImgName, req.ImgIds, req.ImgNames, req.FileIds, req.OptOrg)
	return &model.Result{RetCode: retCode, RetMsg: retMsg}
}

// Exists 判断资讯编码是否存在
func (s *infoServ) Exists(req *info_mod.InfoExtVo) bool {
	sqlStr := "SELECT COUNT(1) AS nums FROM information WHERE states IN (1, 3) AND opt_org=$1 AND info_type=$2 AND fst_title=$3"
	param := make([]interface{}, 0)
	param = append(param, req.OptOrg)
	param = append(param, req.InfoType)
	param = append(param, req.FstTitle)
	if req.InfoId != "" {
		sqlStr += " AND info_id!=$4"
		param = append(param, req.InfoId)
	}
	if dbMap, err := util.GetOne(sqlStr, param...); err == nil && len(dbMap) > 0 {
		if dbMap["nums"].(int64) > 0 {
			return true
		}
	}
	return false
}

// Update 修改资讯
func (s *infoServ) Update(req *info_mod.InfoSaveReq) *model.Result {
	sqlStr := "UPDATE information SET fst_title=$1, sec_title=$2, kind=$3, info_type=$4, sort=$5, src=$6, begin_time=$7, " +
		"end_time=$8, cmted=$9, describ=$10, contents=$11, fst_img_url=$12, img_urls=$13, file_urls=$14, file_names=$15, " +
		"visit_num=$16, good_num=$17, cmt_num=$18, tag_ids=$19, tag_names=$20, upd_time=EXTRACT(EPOCH FROM NOW()), " +
		"fst_img_id=$21, fst_img_name=$22, img_ids=$23, img_names=$24, file_ids=$25 " +
		"WHERE info_id=$26"
	retCode, retMsg := util.CudData(sqlStr, req.FstTitle, req.SecTitle, req.Kind, req.InfoType, req.Sort, req.Src,
		req.BeginTime, req.EndTime, req.Cmted, req.Describ, req.Contents, req.FstImgUrl, req.ImgUrls, req.FileUrls,
		req.FileNames, req.VisitNum, req.GoodNum, req.CmtNum, req.TagIds, req.TagNames,
		req.FstImgId, req.FstImgName, req.ImgIds, req.ImgNames, req.FileIds, req.InfoId)
	return &model.Result{RetCode: retCode, RetMsg: retMsg}
}

// Process 删除资讯
func (s *infoServ) Process(req *info_mod.InfoProReq) *model.Result {
	var (
		param []interface{}
		q     string
		n     = 1
	)
	param = append(param, req.States)
	idList := strings.Split(req.InfoIds, ",")
	for _, curId := range idList {
		n++
		q += "$" + strconv.Itoa(n) + ","
		param = append(param, curId)
	}
	q = q[:len(q)-1]
	sqlStr := "UPDATE information SET states=$1, upd_time=EXTRACT(EPOCH FROM NOW()) WHERE info_id IN (" + q + ")"
	retCode, retMsg := util.CudData(sqlStr, param...)
	return &model.Result{RetCode: retCode, RetMsg: retMsg}
}

// One 获取资讯详情
func (s *infoServ) One(roleId string) *model.Result {
	sqlStr := "SELECT a.info_id, a.fst_title, a.sec_title, a.kind, a.info_type, a.sort, a.src, a.begin_time, a.end_time, " +
		"a.cmted, a.describ, a.contents, a.fst_img_url, a.img_urls, a.file_urls, a.file_names, a.visit_num, a.good_num, " +
		"a.cmt_num, a.tag_ids, a.tag_names, a.states, a.add_time, a.upd_time, a.fst_img_id, " +
		"a.fst_img_name, a.img_ids, a.img_names, a.file_ids, b.type_name, b.type_code " +
		"FROM information a LEFT JOIN sys_type b ON a.info_type=b.type_id WHERE a.info_id=$1"
	if dbMap, err := util.GetOne(sqlStr, roleId); err == nil && len(dbMap) > 0 {
		return &model.Result{RetCode: 1001, RetMsg: "ok", RetData: dbMap}
	} else {
		return &model.Result{RetCode: 1000, RetMsg: "暂无内容"}
	}
}

// Count 获取资讯数量
func (s *infoServ) Count(req *info_mod.InfoPageReq) *model.Result {
	sqlStr := "SELECT COUNT(1) AS nums FROM information WHERE states IN (1, 3) AND kind=$1 AND opt_org=$2"
	var param []interface{}
	param = append(param, req.Kind)
	param = append(param, req.OptOrg)
	var n = 2
	if req.SchName != "" {
		sqlStr += " AND ("
		nameArr := strings.Split(req.SchName, " ")
		for _, name := range nameArr {
			sqlStr += "fst_title LIKE '%'||$" + strconv.Itoa(n+1) + "||'%' OR " +
				"sec_title LIKE '%'||$" + strconv.Itoa(n+2) + "||'%' OR " +
				"tag_names LIKE '%'||$" + strconv.Itoa(n+3) + "||'%' OR "
			param = append(param, name)
			param = append(param, name)
			param = append(param, name)
			n += 3
		}
		sqlStr = sqlStr[:len(sqlStr)-4]
		sqlStr += ")"
	}
	if req.InfoType != "" {
		n++
		sqlStr += " AND info_type=$" + strconv.Itoa(n)
		param = append(param, req.InfoType)
	}
	if req.States != 0 {
		n++
		sqlStr += " AND states=$" + strconv.Itoa(n)
		param = append(param, req.States)
	}
	if req.BeginDate != 0 {
		n++
		sqlStr += " AND begin_time>=$" + strconv.Itoa(n)
		param = append(param, req.BeginDate)
	}
	if req.EndDate != 0 {
		n++
		sqlStr += " AND end_time<=$" + strconv.Itoa(n)
		param = append(param, req.EndDate)
	}
	if dbMap, err := util.GetOne(sqlStr, param...); err == nil && len(dbMap) > 0 {
		return &model.Result{RetCode: 1001, RetMsg: "ok", RetData: dbMap["nums"]}
	} else {
		return &model.Result{RetCode: 1000, RetMsg: "暂无内容"}
	}
}

// Page 获取资讯分页列表
func (s *infoServ) Page(req *info_mod.InfoPageReq) *model.Result {
	sqlStr := "SELECT a.info_id, a.fst_img_url, a.fst_title, b.type_name, a.begin_time, a.end_time, a.states " +
		"FROM information a LEFT JOIN sys_type b ON a.info_type=b.type_id " +
		"WHERE a.states IN (1, 3) AND a.kind=$1 AND a.opt_org=$2"
	var param []interface{}
	param = append(param, req.Kind)
	param = append(param, req.OptOrg)
	var n = 2
	if req.SchName != "" {
		sqlStr += " AND ("
		nameArr := strings.Split(req.SchName, " ")
		for _, name := range nameArr {
			sqlStr += "a.fst_title LIKE '%'||$" + strconv.Itoa(n+1) + "||'%' OR " +
				"a.sec_title LIKE '%'||$" + strconv.Itoa(n+2) + "||'%' OR " +
				"a.tag_names LIKE '%'||$" + strconv.Itoa(n+3) + "||'%' OR "
			param = append(param, name)
			param = append(param, name)
			param = append(param, name)
			n += 3
		}
		sqlStr = sqlStr[:len(sqlStr)-4]
		sqlStr += ")"
	}
	if req.InfoType != "" {
		n++
		sqlStr += " AND a.info_type=$" + strconv.Itoa(n)
		param = append(param, req.InfoType)
	}
	if req.States != 0 {
		n++
		sqlStr += " AND a.states=$" + strconv.Itoa(n)
		param = append(param, req.States)
	}
	if req.BeginDate != 0 {
		n++
		sqlStr += " AND a.begin_time>=$" + strconv.Itoa(n)
		param = append(param, req.BeginDate)
	}
	if req.EndDate != 0 {
		n++
		sqlStr += " AND a.end_time<=$" + strconv.Itoa(n)
		param = append(param, req.EndDate)
	}
	sqlStr += " ORDER BY a.add_time DESC LIMIT $" + strconv.Itoa(n+1) + " OFFSET $" + strconv.Itoa(n+2)
	param = append(param, req.Limit)
	param = append(param, req.Offset)
	if dbMap, err := util.GetAll(sqlStr, param...); err == nil && len(dbMap) > 0 {
		return &model.Result{RetCode: 1001, RetMsg: "ok", RetData: dbMap}
	} else {
		return &model.Result{RetCode: 1000, RetMsg: "暂无内容"}
	}
}

// Sort 获取资讯数量，用于排序
func (s *infoServ) Sort(infoType string) *model.Result {
	sqlStr := "SELECT COUNT(1)+1 AS nums FROM information WHERE states IN (1, 3) AND info_type=$1"
	param := make([]interface{}, 0)
	param = append(param, infoType)
	if dbMap, err := util.GetOne(sqlStr, param...); err == nil && len(dbMap) > 0 {
		return &model.Result{RetCode: 1001, RetMsg: "ok", RetData: dbMap["nums"]}
	} else {
		return &model.Result{RetCode: 1000, RetMsg: "暂无内容"}
	}
}
